home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
usenet
/
sources
/
volume91
/
aplictns
/
quiz_1_0
/
part02
/
screen.c
< prev
Wrap
C/C++ Source or Header
|
1991-04-10
|
18KB
|
658 lines
#include <stdio.h>
#include <string.h> /* strcpy */
#include "screen.h"
void DrawRaisedText();
void EraseQText(), EraseCText();
void DrawQText(), DrawCText();
void colorwindow();
int OpenLibs();
void InitGraphics();
void UpdateMenuGraphState();
void CloseGraphics();
ULONG ehandlemsg();
int handlegadget();
int handlebuttons();
int bhandlemsg();
int handlemenu();
void main();
void redraw();
void about(), abort();
int load();
extern void stractivate(); /* quiz.c */
extern void drawgraph(), cleargraph(); /* graph.c */
extern int whichquestion(); /* graph.c */
/* draw semi-3d-looking text */
void DrawRaisedText(rp,text,slen,x,y)
struct RastPort *rp;
char *text;
int slen, x, y;
{
/* draw it dark */
SetAPen(rp, GREY2);
Move(rp, x+1,y);
Text(rp, text, slen);
/* draw it light */
SetAPen(rp, GREY11);
Move(rp, x-1,y);
Text(rp, text, slen);
/* draw it just right */
SetAPen(rp, GREY7);
Move(rp, x,y);
Text(rp, text, slen);
} /* DrawRaisedText */
/* clear qtext display area */
void EraseQText() {
if (qpb[0])
{ /* clear area */
SetAPen(rp, GREY7);
SetDrMd(rp, JAM1);
RectFill(rp, qpt[2], qpt[3], qpb[2], qpb[3]);
qpb[0] = 0;
} /* if */
} /* EraseQText */
#define QCOLOR GREY3
/* draw the question */
void DrawQText()
{
int slen,theight,textsize;
/* delete old border */
if (qpb[0]) /* don't delete if first time */
{
/* clear the area */
SetAPen(rp, GREY7);
SetDrMd(rp, JAM1);
RectFill(rp, qpt[2], qpt[3], qpb[2], qpb[3]);
} /* if */
slen = strlen(qtext);
if (slen==0) return;
theight = rp->TxHeight;
textsize = slen * rp->TxWidth + 1; /* 1 pixel pad? */
qpt[0] = QX-BORDWIDTH*2;
qpt[1] = QY+theight+BORDWIDTH*2;
qpt[2] = QX-BORDWIDTH*2;
qpt[3] = QY-BORDWIDTH*2;
qpt[4] = QX+textsize+BORDWIDTH*2;
qpt[5] = QY-BORDWIDTH*2;
qpb[0] = QX-BORDWIDTH*2;
qpb[1] = QY+theight+BORDWIDTH*2;
qpb[2] = QX+textsize+BORDWIDTH*2;
qpb[3] = QY+theight+BORDWIDTH*2;
qpb[4] = QX+textsize+BORDWIDTH*2;
qpb[5] = QY-BORDWIDTH*2;
if (slen <= maxqchars) {
/* set border */
DrawBorder(rp,&qtop,0,0);
/* draw black box */
SetAPen(rp, QCOLOR);
SetDrMd(rp, JAM1);
RectFill(rp, qpt[2]+BORDWIDTH, qpt[3]+BORDWIDTH,
qpb[2]-BORDWIDTH, qpb[3]-BORDWIDTH);
/* now draw text */
DrawRaisedText(rp, qtext, slen, QX, QY+baseheight);
} /* if */
else { /* must make bigger window */
char *lastspace = NULL, *s, *r;
int done = 0, numlines = 0, maxlen = 0, i;
/* Have to copy strings and output them after breaking up */
/* qtext. We must know maxlen's value in order to draw */
/* the dark grey rectangle */
char brokentext[MAXLINES][MAXQCHARS];
int sizes[MAXLINES];
r = qtext;
do {
numlines++;
s = r;
while (s<r+maxqchars) {
if (*s == ' ') lastspace = s;
else if (*s == '\0') {done = 1; break;}
s++;
} /* while */
/* this is gross */
/* we found a line */
if (lastspace) {
if (!done) *lastspace = '\0'; /* gulp */
slen = strlen(r); if (slen>maxlen) maxlen = slen;
strncpy(brokentext[numlines-1],r,slen);
sizes[numlines-1] = slen;
/*DrawRaisedText(rp, r, slen, QX, QY+baseheight+theight*(numlines-1));*/
if (!done) *lastspace = ' ';
r = lastspace + 1;
while (*r == ' ') r++; /* skip over any more spaces */
if (!*r) done = 1;
lastspace = NULL;
} /* if lastspace */
else if (done) /* reached the end in this iteration */
{
slen = strlen(r); if (slen>maxlen) maxlen = slen;
strncpy(brokentext[numlines-1],r,slen);
sizes[numlines-1] = slen;
/*DrawRaisedText(rp, r, slen, QX, QY+baseheight+theight*(numlines-1));*/
}
else { /* no breaks */
strncpy(brokentext[numlines-1],r,maxqchars);
sizes[numlines-1] = maxqchars;
/*DrawRaisedText(rp, r, maxqchars, QX, QY+baseheight+theight*(numlines-1));*/
r+=maxqchars; maxlen = maxqchars;
while (*r == ' ') r++; /* skip over any more spaces */
if (!*r) done = 1;
} /* else */
} while ((!done)&&(numlines<MAXLINES));
/* set border -- only 3 must be changed*/
textsize = maxlen * rp->TxWidth + 1; /* 1 pixel pad? */
qpt[4] = QX+textsize+BORDWIDTH;
qpb[2] = QX+textsize+BORDWIDTH;
qpb[4] = QX+textsize+BORDWIDTH;
qpt[1] = QY+theight*numlines+BORDWIDTH;
qpb[1] = QY+theight*numlines+BORDWIDTH;
qpb[3] = QY+theight*numlines+BORDWIDTH;
DrawBorder(rp,&qtop,0,0);
/* draw black box */
SetAPen(rp, QCOLOR);
SetDrMd(rp, JAM1);
RectFill(rp, qpt[2]+BORDWIDTH, qpt[3]+BORDWIDTH,
qpb[2]-BORDWIDTH, qpb[3]-BORDWIDTH);
/* now actually draw the text */
for (i=0;i<numlines;i++)
DrawRaisedText(rp, brokentext[i], sizes[i], QX, QY+baseheight+theight*i);
} /* else */
} /* DrawQText */
/* clear ctext display area */
void EraseCText() {
if (cpb[0])
{ /* clear area */
SetAPen(rp, GREY7);
SetDrMd(rp, JAM1);
RectFill(rp, cpt[2], cpt[3], cpb[2], cpb[3]);
cpb[0] = 0;
} /* if */
} /* EraseCText */
#define CCOLOR 15 /* ? */
/* draw the correct answer */
void DrawCText()
{
int slen, theight, textsize;
/* delete old border if existing */
if (cpb[0])
{ /* clear area */
SetAPen(rp, GREY7);
SetDrMd(rp, JAM1);
RectFill(rp, cpt[2], cpt[3], cpb[2], cpb[3]);
} /* if */
if (ctext==NULL) return;
slen = strlen(ctext);
if (slen==0) return;
theight = rp->TxHeight;
textsize = slen * rp->TxWidth + 1; /* 1 pixel pad? */
cpt[0] = CX-BORDWIDTH*2;
cpt[1] = CY+theight+BORDWIDTH*2;
cpt[2] = CX-BORDWIDTH*2;
cpt[3] = CY-BORDWIDTH*2;
cpt[4] = CX+textsize+BORDWIDTH*2;
cpt[5] = CY-BORDWIDTH*2;
cpb[0] = CX-BORDWIDTH*2;
cpb[1] = CY+theight+BORDWIDTH*2;
cpb[2] = CX+textsize+BORDWIDTH*2;
cpb[3] = CY+theight+BORDWIDTH*2;
cpb[4] = CX+textsize+BORDWIDTH*2;
cpb[5] = CY-BORDWIDTH*2;
if (slen <= maxqchars) {
/* set border */
DrawBorder(rp,&ctop,0,0);
/* draw black box */
SetAPen(rp, CCOLOR);
SetDrMd(rp, JAM1);
RectFill(rp, cpt[2]+BORDWIDTH, cpt[3]+BORDWIDTH,
cpb[2]-BORDWIDTH, cpb[3]-BORDWIDTH);
/* now draw text */
DrawRaisedText(rp, ctext, slen, CX, CY+baseheight);
} /* if */
else { /* must make bigger window */
char *lastspace = NULL, *s, *r;
int done = 0, numlines = 0, maxlen = 0, i;
/* Have to copy strings and output them after breaking up */
/* ctext. We must know maxlen's value in order to draw */
/* the dark grey rectangle */
char brokentext[MAXLINES][MAXQCHARS];
int sizes[MAXLINES];
r = ctext;
do {
numlines++;
s = r;
while (s<r+maxqchars) {
if (*s == ' ') lastspace = s;
else if (*s == '\0') {done = 1; break;}
s++;
} /* while */
/* this is gross */
/* we found a line */
if (lastspace) {
if (!done) *lastspace = '\0'; /* gulp */
slen = strlen(r); if (slen>maxlen) maxlen = slen;
strncpy(brokentext[numlines-1],r,slen);
sizes[numlines-1] = slen;
if (!done) *lastspace = ' ';
r = lastspace + 1;
while (*r == ' ') r++; /* skip over any more spaces */
if (!*r) done = 1;
lastspace = NULL;
} /* if lastspace */
else if (done) /* reached the end in this iteration */
{
slen = strlen(r); if (slen>maxlen) maxlen = slen;
strncpy(brokentext[numlines-1],r,slen);
sizes[numlines-1] = slen;
}
else { /* no breaks */
strncpy(brokentext[numlines-1],r,maxqchars);
sizes[numlines-1] = maxqchars;
r+=maxqchars; maxlen = maxqchars;
while (*r == ' ') r++; /* skip over any more spaces */
if (!*r) done = 1;
} /* else */
} while ((!done)&&(numlines<MAXLINES));
/* set border -- only 3 must be changed*/
textsize = maxlen * rp->TxWidth + 1; /* 1 pixel pad? */
cpt[4] = CX+textsize+BORDWIDTH;
cpb[2] = CX+textsize+BORDWIDTH;
cpb[4] = CX+textsize+BORDWIDTH;
cpt[1] = CY+theight*numlines+BORDWIDTH;
cpb[1] = CY+theight*numlines+BORDWIDTH;
cpb[3] = CY+theight*numlines+BORDWIDTH;
DrawBorder(rp,&ctop,0,0);
/* draw black box */
SetAPen(rp, CCOLOR);
SetDrMd(rp, JAM1);
RectFill(rp, cpt[2]+BORDWIDTH, cpt[3]+BORDWIDTH,
cpb[2]-BORDWIDTH, cpb[3]-BORDWIDTH);
/* now actually draw the text */
for (i=0;i<numlines;i++)
DrawRaisedText(rp, brokentext[i], sizes[i], CX, CY+baseheight+theight*i);
} /* else */
} /* DrawCText */
/* fills in an entire window with color c */
void colorwindow(w,c)
struct Window *w;
int c;
{
SetDrMd(w->RPort, JAM1);
SetAPen(w->RPort, c);
RectFill(w->RPort, 0, 0, w->Width, w->Height);
} /* colorwindow*/
#if 0
void FatalError(s) char *s;
{
printf("%s", s);
CloseGraphics();
exit(1);
} /* FatalError */
#endif
/* Just opens intuition library. Returns 1 if successful, 0 if not */
int iopen=0, gopen=0;
int OpenLibs() {
IntuitionBase = (struct IntuitionBase *)
OpenLibrary("intuition.library", 0);
if (IntuitionBase==NULL) return(0);
iopen = 1;
GfxBase = (struct GfxBase *)
OpenLibrary("graphics.library", 0);
if (GfxBase==NULL) return(0);
gopen=1;
return(1);
} /* OpenLibs */
void InitGraphics() {
if (OpenLibs()==0) FatalError("Couldn't open libraries!\n");
if ((qscreen = OpenScreen(&ns)) == NULL)
FatalError("Couldn't open screen!\n");
vp = &(qscreen->ViewPort);
/* initialize colortable */
LoadRGB4(vp, &mycmap[0], 32);
/* errnw.Screen = qscreen;*/
backnw.Screen = qscreen;
backnw.FirstGadget = &sgadget;
if ((backwindow = OpenWindow(&backnw)) == NULL)
FatalError("Couldn't open backdrop window!\n");
/* if ((ewindow = OpenWindow(&errnw)) == NULL)
FatalError("Couldn't open error window!\n");*/
menustrip[0] = &m1;
menustrip[1] = &m2;
menustrip[0]->NextMenu = menustrip[1];
SetMenuStrip(backwindow,menustrip[0]);
if (qstate.Asking || (!qstate.File[0]))
OffMenu(backwindow, BEGINMENUNUM);
if (qstate.GraphType==BYTRIAL) {
OffMenu(backwindow, TRIALMENUNUM);
OnMenu(backwindow, QUESTMENUNUM);
} /* if */
else if (qstate.GraphType==BYQUESTION)
{
OffMenu(backwindow, QUESTMENUNUM);
OnMenu(backwindow, TRIALMENUNUM);
} /* if */
ShowTitle(qscreen, FALSE);
rp = backwindow->RPort;
/* calculate how many characters can fit in one line of text */
/* note that this method doesn't account for variable-width fonts :-( */
maxqchars = (MAXQX-QX)/rp->TxWidth;
baseheight = rp->TxBaseline;
} /* InitGraphics */
/* This is not very clean, but we need to be able to turn off/on the
correct menu items depending of the state of the graph */
void UpdateMenuGraphState() {
if (qstate.GraphType==BYTRIAL) {
OffMenu(backwindow, TRIALMENUNUM);
OnMenu(backwindow, QUESTMENUNUM);
} /* if */
else if (qstate.GraphType == BYQUESTION) {
OffMenu(backwindow, QUESTMENUNUM);
OnMenu(backwindow, TRIALMENUNUM);
} /* if */
} /* UpdateMenuGraphState */
void CloseGraphics()
{
if (backwindow) {
ClearMenuStrip(backwindow);
while (mes = GetMsg(backwindow->UserPort)) ReplyMsg(mes);
CloseWindow(backwindow);
} /* if backwindow */
if (qscreen) CloseScreen(qscreen);
if (gopen) CloseLibrary(GfxBase);
if (iopen) CloseLibrary(IntuitionBase);
/*OpenWorkBench();*/
/*WBenchToFront();*/
} /* CloseGraphics */
ULONG ehandlemsg(message)
struct IntuiMessage *message;
{
struct IntuiMessage localms;
int i;
UBYTE *s, *d;
ULONG class,code;
s = (UBYTE *)message;
d = (UBYTE *)&localms;
for (i=0;i<sizeof(struct IntuiMessage);i++) *d++=*s++;
ReplyMsg(message);
class = localms.Class;
code = localms.Code;
switch (class)
{
case CLOSEWINDOW:
break;
case REFRESHWINDOW:
case NEWSIZE:
redraw();
default:
break;
} /* switch */
return(class);
} /* ehandlemsg */
int handlegadget(g)
struct Gadget *g;
{
switch (g->GadgetID) {
case STRINGID:
atext = ((struct StringInfo *)(g->SpecialInfo))->Buffer;
/*DrawQText();*/
return(NEWSTRING);
break;
case IMAGEID:
break;
default:
break;
}
return(IGNORE);
} /* handle gadget */
void about() { printf("Quiz by Curtis Eubanks\n"); }
/* returns 1 if successful, 0 if not */
int load() {
if (*sStringInfo.Buffer)
{
strcpy(qstate.File, sStringInfo.Buffer);
history = hindices = (short *)NULL;
CleanUp(FREEALL_MSG);
if (readfile(qstate.File, &buf)) {
qstate.Asking = 1;
return 1;
} /* if */
} /* if */
return 0;
} /* load */
void abort() {
} /* abort */
int handlemenu(code)
ULONG code;
{
ULONG MenuNumber = MENUNUM(code), ItemNumber = ITEMNUM(code);
if ((code != MENUNULL) && (ItemNumber != NOITEM)) {
if (MenuNumber == PROJMENU) {
switch (ItemNumber)
{
case QUITNUM:
return(QUITNOW);
break;
case ABOUTNUM:
about();
break;
case LOADNUM:
if (load()) return(OPENNEWFILE); else return(IGNORE);
break;
case BEGINNUM:
return(STARTASKING);
break;
default:
NonFatalError("Unknown Project Menu selection!\n");
break;
} /* switch */
} /* if project menu */
else if (MenuNumber==OPTMENU) {
switch (ItemNumber)
{
case SWITCHNUM:
return(SWITCHEM);
break;
case IGNORENUM:
qstate.CaseSensitive = !qstate.CaseSensitive;
break;
case ABORTNUM:
abort();
return(ABORTNOW);
break;
case MENUBYTRIAL:
if (qstate.GraphType != BYTRIAL && qstate.GraphType) {
qstate.GraphType = BYTRIAL;
OffMenu(backwindow, TRIALMENUNUM);
OnMenu(backwindow, QUESTMENUNUM);
cleargraph();
drawgraph();
stractivate();
}
return IGNORE;
break;
case MENUBYQUESTION:
if (qstate.GraphType != BYQUESTION && qstate.GraphType) {
qstate.GraphType = BYQUESTION;
OffMenu(backwindow, QUESTMENUNUM);
OnMenu(backwindow, TRIALMENUNUM);
cleargraph();
drawgraph();
stractivate();
}
return IGNORE;
break;
default:
NonFatalError("Unknown Option Menu selection!\n");
break;
} /* switch itemnumber */
} /* if option menu */
} /* if non-null menu selection */
return(IGNORE);
} /* handlemenu */
/* handle button presses */
int handlebuttons(code, mousex, mousey)
ULONG code;
SHORT mousex, mousey;
{
if (code == SELECTDOWN) {
int q;
#ifdef DEBUG
printf("mouse at %d, %d\n", mousex, mousey);
#endif
if ((qstate.GraphType == BYQUESTION) &&
((q=whichquestion(mousex, mousey))!=-1))
{ /* in graph.c */
newquestion = q; /* global, yucky */
return DISPLAYQ;
} /* if q != -1 */
} /* if code */
return IGNORE;
} /* handlebuttons */
int bhandlemsg(message)
struct IntuiMessage *message;
{
struct IntuiMessage localms;
int i;
UBYTE *s, *d;
ULONG class,code;
s = (UBYTE *)message;
bloop:
d = (UBYTE *)&localms;
/* copy message */
for (i=0;i<sizeof(struct IntuiMessage);i++) *d++=*s++;
ReplyMsg(message);
class = localms.Class;
code = localms.Code;
switch (class)
{
case REFRESHWINDOW: /* ugh. this hurts */
/* any more REFRESHWINDOW msgs waiting? */
if (mes = GetMsg(backwindow->UserPort))
{ /* don't redraw if more than one REFRESHWINDOW in a row */
/* printf("waiting: %d ",mes->Class);
if (mes->Class==REFRESHWINDOW) printf("(refresh)\n");
else printf("(not refresh)\n");*/
s = (UBYTE *)mes; message = mes; /* legal? */
if (mes->Class==REFRESHWINDOW) goto bloop;
else { /* some other message. Redraw and process it */
redraw();
goto bloop;
} /* else */
} /* if */
else redraw();
break;
case GADGETUP:
return(handlegadget((struct Gadget *)localms.IAddress));
break;
case MENUPICK:
return(handlemenu(code));
break;
case MOUSEBUTTONS:
return(handlebuttons(code, localms.MouseX, localms.MouseY));
break;
default:
break;
} /* switch */
return(IGNORE);
} /* bhandlemsg */
#if 0
void main(argc, argv)
int argc;
union {
char **args;
struct WBStartup *msg;
} argv;
{
ULONG val=0;
if (argc>2) {
/* errnw.DetailPen = atoi(argv.args[1]);
errnw.BlockPen = atoi(argv.args[2]);*/
}
if (argc>4) {
ns.DetailPen = atoi(argv.args[3]);
ns.BlockPen = atoi(argv.args[4]);
}
InitGraphics();
redraw();
/* WaitPort(ewindow->UserPort);*/
while(1) {
while (mes = GetMsg(backwindow->UserPort)) val=bhandlemsg(mes);
if (val == QUITNUM) break;
/* while (mes = GetMsg(ewindow->UserPort)) val=ehandlemsg(mes);*/
if (val == CLOSEWINDOW) break;
}
CloseGraphics();
} /* main */
#endif
#define BaseX 30
#define BaseY 40
#define Bsize 12
void redraw() {
colorwindow(backwindow, GREY7);
SetDrMd(rp, JAM1);
/* draw gadget's border */
DrawBorder(rp,&ibt,0,0);
if (qtext) DrawQText();
if (qstate.ShowingAns) DrawCText();
if (qstate.GraphType) drawgraph();
RefreshGadgets(&sgadget, backwindow, NULL);
} /* redraw */